using System;
using Magiq.Delete;
using Magiq.Insert;
using Magiq.Query;
using Magiq.Support;
using Magiq.Update;

namespace Magiq.Providers.Objects
{
    public class MagiqToObjects : MagiqProvider
    {
        #region IMagiqProvider Members

        public override IUpdateStrategy GetUpdateStrategy<T>(IUpdate<T> update) 
        {
            return new UpdateStrategy<T>(update);
        }

        public override IDeleteStrategy GetDeleteStrategy<T>(IDelete<T> delete) 
        {
            return new DeleteStrategy<T>(delete);
        }

        public override IInsertStrategy GetInsertStrategy<TSource, TDestination, TNew>(
            IInsert<TSource,TDestination, TNew> insert) 
        {
            return new InsertStrategy<TSource, TDestination, TNew>(insert, MagiqConfigurator.ForInsertDestination(insert));
        }

        public override IInsertDestination<TNew> GetInsertDestination<TSource, TDestination, TNew>(
            IInsert<TSource,TDestination, TNew> insertDestinationDefinition)
        {
            var source = new EnumerableSource(insertDestinationDefinition.Destination);

            if (source.IsQuery)
                throw new InvalidOperationException("Items cannot be added to queries.");
            
            return
                new ListInsertDestination<TNew>(
                    new EnumerableSource(insertDestinationDefinition.Destination).List);
        }

        public override IQueryStrategy<TChild> GetQueryStrategy<T,TChild>(QueryInfo<T,TChild> queryInfo)
        {
            return new QueryInfoQueryStrategy<T, TChild>(queryInfo);
        }

        public override MagiqProviderOrderStrategy OrderStrategy
        {
            get { return MagiqProviderOrderStrategy.QueryInfoInParent; }
        }

        public override IEnumerableStrategy<TNew> GetObjectSourceStrategy<TSource, TNew>(InsertSource<TNew> source)
        {
            return new InsertSourceEnumerableStrategy<TNew>(source);
        }

        public override IInsertStrategy GetBulkInsertStrategy<TSource, TDestination, TNew>(IInsert<TSource, TDestination, TNew> insert)
        {
            return GetInsertStrategy(insert);
        }

        #endregion
    }
}